package com.example.demo1;

import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Align;
import android.graphics.Paint.FontMetricsInt;
import android.graphics.Paint.Style;
import android.graphics.Typeface;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;

public class HorPickView extends View {

	public static final String TAG = "PickerView";
	/**
	 * text之间间距和minTextSize之比
	 */
	public static final float MARGIN_ALPHA = 2.8f;
	/**
	 * 自动回滚到中间的速度
	 */
	public static final float SPEED = 8;
	private List<String> mDataList = new ArrayList<String>();
	/**
	 * 选中的位置，这个位置是mDataList的中心位置，一直不变
	 */
	private int mCurrentSelected = -1;
	private Paint mPaint;
	private float mMaxTextSize = 40;
	private float mMinTextSize = 40;
	private float currentTextSize = 20;
	private float mMaxTextAlpha = 255;
	private float mMinTextAlpha = 0;
	private int mViewHeight;
	private int mViewWidth;
	private float mLastDownX;
	/**
	 * 滑动的距离
	 */
	public float mMoveLen = 0;
	private boolean isInit = false;
	private onHorSelectListener mSelectListener;
	private Timer timer;
	private MyTimerTask mTask;
	private Typeface currentTypeface;
	private float mLastDownY;
	private boolean scrollEnable = true;// 是否可滑动
	private boolean onScrollChange;
	private int mFistSelected;//初始选中

	Handler updateHandler = new Handler() {

		@Override
		public void handleMessage(Message msg) {
			if (Math.abs(mMoveLen) < SPEED) {
				mMoveLen = 0;
				if (mTask != null) {
					mTask.cancel();
					mTask = null;
					if (mCurrentSelected!=mFistSelected) {
						mFistSelected = mCurrentSelected;
						performSelect();
					}
				}
			} else
				// 这里mMoveLen / Math.abs(mMoveLen)是为了保有mMoveLen的正负号，以实现上滚或下滚
				mMoveLen = mMoveLen - mMoveLen / Math.abs(mMoveLen) * SPEED;
			invalidate();
		}

	};

	public HorPickView(Context context) {
		super(context);
		init();
	}

	public HorPickView(Context context, AttributeSet attrs) {
		super(context, attrs);
		init();
	}

	public void setOnSelectListener(onHorSelectListener listener) {
		mSelectListener = listener;
	}

	public void performSelect() {
		if (mSelectListener != null)
			mSelectListener.onSelect(mCurrentSelected);
	}

	/**
	 * 设置数据源的方法
	 * 
	 * @param datas
	 */
	public void setData(List<String> datas) {
		if (datas == null) {
			return;
		}
		mDataList = datas;
		mCurrentSelected = 0;
		invalidate();
	}

	/**
	 * 设置是否可滑动
	 * 
	 * @param scrollEnable
	 */
	public void setScrollEnable(boolean scrollEnable) {
		this.scrollEnable = scrollEnable;
		invalidate();
	}

	public void setTextSize(float textSize) {
		this.currentTextSize = textSize;
		invalidate();
	}

	public void setTypeFace(Typeface currentTypeface) {
		this.currentTypeface = currentTypeface;
		invalidate();
	}

	/**
	 * 设置当前选择文字
	 * 
	 * @param datas
	 */
	public void setSelected(int selected) {
		mCurrentSelected = selected;
		mFistSelected = mCurrentSelected;
		invalidate();
	}

	/**
	 * 获取当前选择位置
	 * 
	 * @param datas
	 */
	public int getSelected() {
		return mCurrentSelected;
	}

	public void moveHeadToTail() {
		if (mDataList != null && mDataList.size() > 0) {
			if (mCurrentSelected < mDataList.size() - 1) {
				mCurrentSelected++;
			}
		}
	}

	public void moveTailToHead() {
		if (mCurrentSelected > 0) {
			mCurrentSelected--;
		}
	}

	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		super.onMeasure(widthMeasureSpec, heightMeasureSpec);
		mViewHeight = getMeasuredHeight();
		mViewWidth = getMeasuredWidth();
		// 按照View的高度计算字体大小
		mMaxTextSize = mViewHeight / 4.0f;
		mMinTextSize = mMaxTextSize / 1.0f;
		// 文字变小的时候的大小
		// mMinTextSize = mMaxTextSize;
		isInit = true;
		invalidate();
	}

	private void init() {
		timer = new Timer();
		mDataList = new ArrayList<String>();
		mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
		mPaint.setStyle(Style.FILL);
		mPaint.setTextAlign(Align.CENTER);
		mPaint.setTypeface(currentTypeface);
		mPaint.setTextSize(currentTextSize);
		mPaint.setColor(Color.WHITE);
	}

	@Override
	protected void onDraw(Canvas canvas) {
		super.onDraw(canvas);
		// 根据index绘制view
		if (isInit)
			drawData(canvas);
	}

	private void drawData(Canvas canvas) {
		// 先绘制选中的text再往上往下绘制其余的text
		// 先绘制选中的text再往上往下绘制其余的text
		float scale = parabola((mViewWidth - mViewWidth / 2) / 2.0f, mMoveLen);
		float size = (mMaxTextSize - mMinTextSize) * scale + mMinTextSize;
		// float f = ((mMaxTextAlpha - mMinTextAlpha) * scale + mMinTextAlpha);
		mPaint.setAlpha((int) ((mMaxTextAlpha - mMinTextAlpha) * scale + mMinTextAlpha));
		mPaint.setTextSize(currentTextSize);
		mPaint.setTypeface(currentTypeface);
		// text居中绘制，注意baseline的计算才能达到居中，y值是text中心坐标
		float x = (float) (mViewWidth / 2.0 + mMoveLen);
		float y = (float) (mViewHeight / 2.0);
		FontMetricsInt fmi = mPaint.getFontMetricsInt();
		float baseline = (float) (y - (fmi.bottom / 2.0 + fmi.top / 2.0));
		if (mDataList != null && mDataList.size() > 0) {
			canvas.drawText(mDataList.get(mCurrentSelected), x, baseline,
					mPaint);
		}

	}

	/**
	 * 抛物线
	 * 
	 * @param zero
	 *            零点坐标
	 * @param y
	 *            偏移量
	 * @return scale zero的y次方
	 */
	private float parabola(float zero, float y) {
		float f = (float) (1 - Math.pow(Math.abs(y) / zero, 1));
		return f < 0 ? 0 : f;
	}

	@Override
	public boolean onTouchEvent(MotionEvent event) {
		switch (event.getActionMasked()) {
		case MotionEvent.ACTION_DOWN:
			getParent().requestDisallowInterceptTouchEvent(true);
			doDown(event);
			onScrollChange = false;
			mLastDownY = event.getY();
			break;
		case MotionEvent.ACTION_MOVE:
			if (Math.abs(event.getY() - mLastDownY) > 88) {
				getParent().requestDisallowInterceptTouchEvent(false);
			}
			if (!scrollEnable) {
			} else if (mCurrentSelected == 0 && event.getX() - mLastDownX > 0) {
			} else if (mCurrentSelected == mDataList.size() - 1
					&& event.getX() - mLastDownX < 0) {
			} else {
				doMove(event);
			}
			break;
		case MotionEvent.ACTION_UP:
			getParent().requestDisallowInterceptTouchEvent(false);
			doUp(event);
			break;
		case MotionEvent.ACTION_CANCEL:
			getParent().requestDisallowInterceptTouchEvent(false);
			doUp(event);
			break;
		}
		return true;
	}

	private void doDown(MotionEvent event) {
		if (mTask != null) {
			mTask.cancel();
			mTask = null;
		}
		mLastDownX = event.getX();
	}

	public void movetobefore(MotionEvent event) {
		// 往下滑超过离开距离
		getParent().requestDisallowInterceptTouchEvent(true);
		doDown(event);
		onScrollChange = false;
		mLastDownY = event.getY();
	}

	/**
	 * 移动到下一个
	 */
	public void movetonext(MotionEvent event) {
		// 往下滑超过离开距离
		if (Math.abs(event.getY() - mLastDownY) > 88) {
			getParent().requestDisallowInterceptTouchEvent(false);
		}
		if (!scrollEnable) {
		} else if (mCurrentSelected == 0 && event.getX() - mLastDownX > 0) {
		} else if (mCurrentSelected == mDataList.size() - 1
				&& event.getX() - mLastDownX < 0) {
		} else {
			doMove(event);
		}
	}

	public void up() {
		mMoveLen = 0;
		mFistSelected = -1;
		if (mTask != null) {
			mTask.cancel();
			mTask = null;
		}
		mTask = new MyTimerTask(updateHandler);
		timer.schedule(mTask, 0, 5);
	}

	/**
	 * 移动到上一个
	 */
	public void movetoup(MotionEvent event) {
		doUp(event);
	}

	private void doMove(MotionEvent event) {
		if (!onScrollChange) {
			mMoveLen += event.getX() - mLastDownX;
			if (mMoveLen > (mViewWidth - mViewWidth / 2) / 3) {
				// 往左滑超过离开距离
				moveTailToHead();
				onScrollChange = true;
				// mMoveLen = mMoveLen - MARGIN_ALPHA * mMinTextSize * 4;
				mMoveLen = mMoveLen - (mViewWidth - mViewWidth / 4);
			} else if (mMoveLen < -(mViewWidth - mViewWidth / 2) / 3) {
				// 往右滑超过离开距离
				moveHeadToTail();
				onScrollChange = true;
				mMoveLen = mMoveLen + (mViewWidth - mViewWidth / 4);
				// mMoveLen = mMoveLen + MARGIN_ALPHA * mMinTextSize * 4;
			}
			mLastDownX = event.getX();
			invalidate();
		} else {
			if (Math.abs(mMoveLen) < 20) {
				// mMoveLen = 0;
			}else{
				mMoveLen += (event.getX() - mLastDownX);
				mLastDownX = event.getX();
				invalidate();
			}
		}
	}

	private void doUp(MotionEvent event) {
		// 抬起手后mCurrentSelected的位置由当前位置move到中间选中位置
		if (Math.abs(mMoveLen) < 0.0001) {
			mMoveLen = 0;
			return;
		}
		mMoveLen = 0;
		if (mTask != null) {
			mTask.cancel();
			mTask = null;
		}
		mTask = new MyTimerTask(updateHandler);
		timer.schedule(mTask, 0, 5);

	}

	class MyTimerTask extends TimerTask {
		Handler handler;

		public MyTimerTask(Handler handler) {
			this.handler = handler;
		}

		@Override
		public void run() {
			handler.sendMessage(handler.obtainMessage());
		}

	}

	public interface onHorSelectListener {
		void onSelect(int position);
	}
}